<?php
namespace app\admin\controller;

use think\Controller;
use think\facade\Session;
use think\facade\Config;

class Base extends Controller{
    protected $unAuth = ['same'];
    protected $userInfo = null;
    protected $model = null;
    //
    protected function initialize(){
        $session_name = Config::get('app.session_name');
        if(Session::get($session_name) == null){
            $this->redirect(url('Login/index'));
        }
        $this->userInfo = Session::get($session_name);
        $name = $this->request->module().'/'.$this->request->controller().'/'.$this->request->action(true);
        if(!in_array($this->request->action(), $this->unAuth) && !authcheck($name, $this->userInfo['aid'])){
            echo \json_encode($this->response('没有操作权限', false, '', 300));
            exit;
        }
    }
    //首页
    public function index(){
        if(method_exists($this, '_before_index')){
            $this->_before_index();
        }
        $model = model($this->model);
        $map = $this->_map($model);
        if(method_exists($this, '_filter')){
            $map = $this->_filter($map);
        }
        $this->_list($model, $map);
        return $this->fetch();
    }
    //新增
    public function add(){
        if($this->request->isPost()){
            $data = $this->request->post();
            if(method_exists($this, '_before_insert')){
                $data = $this->_before_insert($data);
            }
            $result = $this->validate($data, 'app\admin\validate\\'.$this->model.'.add');
            if(true !== $result){
                $return = $this->response($result, false, '', 300);
                return json($return);
            }
            $model = model($this->model);
            $lastid = $model->strict(false)->insertGetId($data);
            if($lastid){
                if(method_exists($this, '_after_add')){
                    $this->_after_add($data, $lastid);
                }
                $return = $this->response('新增数据保存成功!', true, url($this->request->controller().'/index'), 200);
                return json($return);
            }
            $return = $this->response('新增数据保存失败', false, '', 300);
            return json($return);
        }
        if(method_exists($this, '_before_add')){
            $this->_before_add();
        }
        return $this->fetch();
    }
    //修改
    public function edit(){
        if($this->request->isPost()){
            $data = $this->request->post();
            if(method_exists($this, '_before_save')){
                $data = $this->_before_save($data);
            }
            $result = $this->validate($data, 'app\admin\validate\\'.$this->model.'.edit');
            if(true !== $result){
                $return = $this->response($result, false, '', 300);
                return json($return);
            }
            $res = model($this->model)->allowField(true)->update($data);
            if($res){
                if(method_exists($this, '_after_edit')){
                    $this->_after_edit($data);
                }
                $return = $this->response('数据保存成功!', true, url($this->request->controller().'/index'), 200);
                return json($return);
            }
            $return = $this->response('数据保存失败!', false, '', 300);
            return json($return);
        }
        if(method_exists($this, '_before_edit')){
            $this->_before_edit();
        }
        $key = $this->request->param('key', '', 'trim');
        $val = $this->request->param('val', '', 'trim');
        if($key == '' || $val == ''){
            $return = $this->response('无效参数!', false, '', 300);
            return json($return);
        }
        $map = [$key=>$val];
        $list = model($this->model)->where($map)->findOrEmpty()->toArray();
        if(method_exists($this, '_filter_edit')){
            $list = $this->_filter_edit($list);
        }
        $this->assign('list', $list);
        return $this->fetch();
    }
    //删除
    public function del(){
        $model = model($this->model);
        $pk = $model->getPk();
        $map = [];
        $ids = trim($this->request->get('delids', ''));
        if($ids != ''){
            $idsArr = explode(',', $ids);
            foreach($idsArr as $kk => $vv){
                $kk = trim($vv);
                if($kk == ''){
                    unset($idsArr[$kk]);
                }
            }
            $map = $idsArr ? [$pk => $idsArr] : [];
        }
        if(!$map){
            $key = $this->request->param('key', '', 'trim');
            $val = $this->request->param('val', '', 'trim');
            if($key == '' || $val == ''){
                $return = $this->response('键或值为空!', false, '', 300);
                return json($return);
            }
            if($pk != $key){
                $return = $this->response('参数不是主键', false, '', 300);
                return json($return);
            }
            $map = [$key => [$val]];
        }
        if(method_exists($this, '_filter_del')){
            $filter = $this->_filter_del();
            $diff = array_diff($map[$pk], $filter);
            if(!$diff){
                $return = $this->response('禁止删除', false, '', 300);
                return json($return);
            }
            $map[$pk] = $diff;
        }
        $rows = $model->where($map)->select()->toArray();
        if(!$rows){
            $return = $this->response('你要删除的行不存在', false, '', 300);
            return json($return);
        }
        $res = $model->where($map)->delete();
        if($res){
            if(method_exists($this, '_after_del')){
                $this->_after_del($rows);
            }
            $return = $this->response('删除成功', false, url($this->request->controller().'/index'), 200);
            return json($return);
        }
        $return = $this->response('删除失败', false, '', 300);
        return json($return);
    }
    //验证字段是否存在
    public function same(){
        $data = $this->request->post();
        if(is_array($data)){
            $model = model($this->model);
            $fields = $model->getTableFields();
            foreach($data as $key => $row){
                $key = trim($key);
                $row = trim($row);
                if($this->request->route($key, '', 'urldecode') == $row){
                    continue;
                }
                if(in_array($key, $fields) && $key != ''){
                    $tmp = $model->where([$key=>$row])->findOrEmpty()->toArray();
                    if($tmp){
                        return json(['data'=>['error'=>'已经存在']]);
                    }
                }
            }
        }
        return json(['data'=>['ok'=>'可用']]);
    }
    //返回查询条件
    protected function _map(\think\Model $model){
        $map = [];
        $keyArr = $this->request->post('keys', []);
        if(is_array($keyArr)){
            $varArr = $model->getTableFields();
            foreach($keyArr as $var => $val){
                $val = trim($val);
                if(in_array($var, $varArr) && $val != ''){
                    if(is_numeric($val) && strpos($var, 'id') !== false){
                        $map[] = [$var, '=', $val];
                    }else{
                        $map[] = [$var, 'like', '%'.$val.'%'];
                    }
                }
            }
        }
        $this->assign('keys', $keyArr);
        return $map;
    }
    //
    protected function _list(\think\Model $model, array $map){
        $order = $this->request->post('orderField', $model->getPk());
        !in_array($order, $model->getTableFields()) ? $order = $model->getPk() : null;
        $sort = $this->request->post('orderDirection', 'desc');
        !in_array($sort, ['asc', 'desc']) ? $sort = 'desc' : null;
        $currentPage = $this->request->post('pageCurrent/d', 1);
        $limit = $this->request->post('pageSize/d', 20);
        $count = $model->where($map)->count();
        if($count > 0){
            $list = $model->where($map)->order($order, $sort)->page($currentPage, $limit)->select()->toArray();
            if(method_exists($this, '_after_list')){
                $list = $this->_after_list($list);
            }
        }else{
            $list = [];
        }
        $this->assign('list', $list);
        $this->assign('totalCount', $count);
        $this->assign('pageCurrent', $currentPage);
        $this->assign('pageSize', $limit);
        $this->assign('orderField', $order);
        $this->assign('orderDirection', $sort);
        return true;
    }
    //记录日志
    protected function log($log, $row = []){
        $log = $this->_log_info($log);
        if(in_array($log['action'], ['add', 'edit', 'del'])){
            $log['data'] = serialize($row);
        }
        model('ActionLog')->insert($log);
    }
    //批量记录日志
    protected function logAll($logs){
        foreach($logs as $key => $log){
            $row = $log['row'];
            unset($log['row']);
            $logs[$key] = $this->_log_info($log);
            $logs[$key]['data'] = serialize($row);
        }
        model('ActionLog')->insertAll($logs);
    }
    //通用日志信息
    protected function _log_info($log){
        $log['aid'] = $this->userInfo['aid'];
        $log['model'] = $this->model;
        $action = $this->request->action(true);
        $action = in_array($action, ['setProduct', 'setTpl', 'setDeny', 'setPage']) ? 'batch' : $action;
        $log['action'] = in_array($action, ['add', 'edit', 'del', 'copy', 'batch']) ? $action : 'none';
        $log['ip'] = $this->request->ip();
        $log['agent'] = $this->request->header('user-agent');
        $log['addtime'] = time();
        return $log;
    }
    /**
     * 
     * @param string $message 可选。信息内容。
     * @param boolean $closeCurrent 可选。是否关闭当前窗口(navtab或dialog)。
     * @param string $tabid 可选。待刷新navtab id，多个id以英文逗号分隔开，当前的navtab id不需要填写，填写后可能会导致当前navtab重复刷新。
     * @param int $statusCode 必选。状态码(ok = 200, error = 300, timeout = 301)，可以在BJUI.init时配置三个参数的默认值。
     * @return array
     */
    protected function response($message, $closeCurrent = true, $tabid = '', $statusCode = 200){
        return [
            'statusCode' => $statusCode,
            'message' => $message,
            'tabid' => $tabid, 
            'dialogid' => '', //string	可选。待刷新dialog id，多个id以英文逗号分隔开，请不要填写当前的dialog id，要控制刷新当前dialog，请设置dialog中表单的reload参数。
            'divid' => '', //string	可选。待刷新div id，多个id以英文逗号分隔开，请不要填写当前的div id，要控制刷新当前div，请设置该div中表单的reload参数。
            'closeCurrent' => $closeCurrent, 
            'forward' => '', //string	可选。跳转到某个url。
            'forwardConfirm' => '', //string	可选。跳转url前的确认提示信息。
        ];
    }
    //空
    public function _empty(){
        exit('<-404->');
    }
}
